#include "table.h"
#include "show_info.h"
#include "node.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

void print_row(Row *row)
{
    printf("(%d, %s, %s)\n", row->id, row->username, row->email);
};

Table *db_open(const char *filename)
{
    Pager *new_page = pager_open(filename);
    assert(new_page != NULL);
    Table *table = malloc(sizeof(Table));
    table->pager = new_page;
    table->root_page_num = 0;

    if (new_page->num_pages == 0)
    {
        // 新的数据库文件，初始化0页面作为叶节点
        Node *root_node = (Node *)get_page(new_page, 0);
        initialize_leaf_node(root_node);
        root_node->is_root = true;
    }
    return table;
};

void db_close(Table *table)
{
    // 前面整页整页的写入
    Pager *pager = table->pager;
    // 写入完了，要释放内存
    for (int i = 0; i < pager->num_pages; i++)
    {
        if (pager->pages[i] == NULL)
        {
            continue;
        }
        pager_flush(pager, i);
        free(pager->pages[i]);
        pager->pages[i] = NULL;
    }

    int res = fclose(pager->file_descriptor);
    if (res < 0)
    {
        printf("error closing file\n");
        exit(EXIT_FAILURE);
    }
    free(pager);
    free(table);
};

// source --> destination 把row 写入void *
void serialize_row(Row *source, void *destination)
{
    memcpy(destination + ID_OFFSET, &(source->id), ID_SIZE);
    memcpy(destination + USERNAME_OFFSET, &(source->username), USERNAME_SIZE);
    memcpy(destination + EMAIL_OFFSET, &(source->email), EMAIL_SIZE);
};

// destination --> source 从void * 拿取 row
void deserialize_row(void *source, Row *destination)
{
    memcpy(&(destination->id), source + ID_OFFSET, ID_SIZE);
    memcpy(&(destination->username), source + USERNAME_OFFSET, USERNAME_SIZE);
    memcpy(&(destination->email), source + EMAIL_OFFSET, EMAIL_SIZE);
};

Cursor *table_start(Table *table)
{
    Cursor *cursor =table_find(table,0);
    Node *node=(Node *)get_page(table->pager,cursor->page_num);
    cursor->end_of_table=(node->num_cells==0);

};

/*
    Return the position of the given key.
    If the key is not present, return the position
    where it should be inserted
*/
Cursor *table_find(Table *table, uint32_t key)
{
    Node *root =(Node *) get_table_root(table);
    if (root->node_type == NODE_LEAF)
    {
        return leaf_node_find(table, table->root_page_num, key);
    }
    else
    {
        return internal_node_find(table, table->root_page_num, key);
       
    }
};

// 迭代器前进一位
void cursor_advance(Cursor *cursor)
{
    //[0,row_num) row_num是最后一位，哨兵，
    if (cursor->end_of_table == false)
    {
        Node *node=(Node*)get_page(cursor->table->pager,cursor->page_num);
        if(cursor->cell_num < node->num_cells){
            cursor->cell_num++;
        }
        if(cursor->cell_num == node->num_cells){
            if(node->next_leaf_page!=0){
                cursor->page_num=node->next_leaf_page;
                cursor->cell_num=0;
                Node *next_node=(Node *)get_page(cursor->table->pager,node->next_leaf_page);
                cursor->end_of_table=(next_node->num_cells==0);
            }
            else{
                cursor->end_of_table=true;
            }
        }
    }
};

//  获取行数为迭代器对应行的首地址
Leaf *cursor_value(Cursor *cursor)
{
    Node *node = (Node *)get_page(cursor->table->pager,cursor->page_num);
    return &(node->rows[cursor->cell_num]);
};